package org.xqh.utils.encrypt;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.TreeMap;

/**
 * Description: AES+RSA签名，加密 验签，解密
 *
 * @author: wubaoguo
 * @email: wustrive2008@gmail.com
 * @date: 2015/8/13 15:12
 */
public class MainTest {
    /**
     * 生成 私钥 公钥
     * @see RSAUtils generateKeyPair
     */
    public static final String clientPrivateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7M+lHgqKUKaJ4qHLrLpUxLZwd0opc0hImHNs8+cHwyCNJJK+wC8xx0mM598fBPD1S91M8vwRSbtFqj1MJZVFT8/3Y8fkEqqZc87N3XLlrepBjLCXF+juLkBNCZcYHTQV8rJpbEwpfeQlEjgirXZsxCdsqxHSo6Ja7AKYbCSn2nNTSn1BgyqwUfR7lNO2pnXBC0OhHX0fR/CAJZLpFjh8dELYn9ZFwa6l2b1I2zejomh6XDEfLS8y9yU6CKLo2k8C12YMiG376DIRVva2DIwk/JpN5Bu5V9ZutHG1dqmFoQUj/RLj9mCXETm03yiFvN4pUYs2ZRkQrs8gc+tmX2SDpAgMBAAECggEAPDDkwOlv/NOmOcVvrc68iaNwnuYjNtUUoMyGcYScpx6yucHh+2jPw4kx/mF9CNSloxeC2/VPHnIjQ2/x8wNwst2wsSCcQLPd6eUxvx9BPx2Zb0mym4Vpv+YDS0YN9ir9qKiWuNHWc/wmzrQcdX0TeSECJy4jlGu0i0waHHdF1tTo7I93KJj3gsPmmfkIRDRayWLhFL2K2DGyMk7fL7UYZET+X4Vp+F3hp0qxbZW2D3cUlS6Sx3rN91+OzW+axR8oDRG1R8r7cDGrDc4oOBgkzzgRIMDwJOufeBm8OC7Eo3B0NNUHiRYJKqaATEIqIpxdeF+sVKAkBIBIUUDrgmO4AQKBgQDw7fIFXx+mqjvxUoGyN/O6pX4ARnbmn01Zg0PIlYWs1UdFlKB5G02VwHSAIP5UocCkGueKbt6H5kDeITH4IDVBaOlGolYj7K8ihrJLiXy+CKJmTx7OsqRGeochiQF3xxURosyB2pC4eCeNTGjA4aGiyh4CpRck9Qw84FRR5twhWQKBgQDG6aEAdegONsyhQXQH93AvUxk+BZbwYyAq+GluG9zOf2liIu8fvvW35mzRA0IGgo8s+OXbnGhX3WT8kGmJqM/bGCR/DnGJwyV1QNcFX7H+iY4V7NiP60pIIPogp5/QuNNKimz8QyGkGsh3gNRfhez8ecfxY5t7SzTlzMTkkLr6EQKBgDg4fjpsqRkeLmCwzR0GW3SZe56a0tIcKFOUAvRCl+/t0PTWqt+31FH2l/jyOgcLu8VPlepC1uDFhSuQeXWaJnM+BPl7ljhJ2dBnuCFSUu6RWzweiGTZYOYlX3Ue4F3P8gWshKZkl1LEjw4031jrDenL2lbpqU3xdMqb2nFGOuX5AoGAFYWj0Pvw7tDJFU2Ss2X3cndoTMioCzx+d4fHSI2lN4abrW2gN+wehBZfgcH7e97WhQQtQrTKqW8gBR/O+4ETdF5JXKIAcOp3fBdW7JLtHGBfykmFKRVJRUKkLbJVXW0SF4egwS62Th5DwIJk+CzydmLq2lhvs0hw4chlKWHriTECgYEAgOT42fTSesgSf4EPygB02fI9iHTn2K/Ew50rfgZdBjPsnSAVDu0rqguLnL2mWh4/AMOUJhksrnBtam1vKktrXdBTwE8K/vCF14PBBNMNMsjqsQBo+Le6NI0lf7JUJUjU0jKlwp9y13k0E4209fMZkL9vrnR7SQcKXQ/GSjZ6gkQ=";

    public static final String clientPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzPpR4KilCmieKhy6y6VMS2cHdKKXNISJhzbPPnB8MgjSSSvsAvMcdJjOffHwTw9UvdTPL8EUm7Rao9TCWVRU/P92PH5BKqmXPOzd1y5a3qQYywlxfo7i5ATQmXGB00FfKyaWxMKX3kJRI4Iq12bMQnbKsR0qOiWuwCmGwkp9pzU0p9QYMqsFH0e5TTtqZ1wQtDoR19H0fwgCWS6RY4fHRC2J/WRcGupdm9SNs3o6JoelwxHy0vMvclOgii6NpPAtdmDIht++gyEVb2tgyMJPyaTeQbuVfWbrRxtXaphaEFI/0S4/ZglxE5tN8ohbzeKVGLNmUZEK7PIHPrZl9kg6QIDAQAB";

    public static final String serverPrivateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCniyN58WDh9KQnAhb2SHaPsd29A4NJ2jgVSQu8kM8k7KzG9aH6dSuSx0d+FYSBKY9pFGTqp0AGcFeReVJ/H2oC+LHg5FrYpHpF7sGJJ+fxVD9PyyfJXRa9+L6Je+d4AW7PO2GOJFlQhIxp3NiepPUFQY1tR1e6PeGAbNsIkW2alXYPaUFfRIrr+PExUKIIz/xABnUSvsTyaMtbbNCIYnpDfWdFEFeuqlaNZK+I+EpprHcjwincImJJreH/0aDJeZlX4LOo7KYhbt0WYY/hgq86Y4nZfPw2lh15Al0nnuUIGRO8+GJU4z0sSRqS7l3dx5oshH0rNJaPEQVXvIfdUMaJAgMBAAECggEAaIdugs4N2+t93rh3CwD6t3wJE7v1VUZIZz9Di0ntcuQWh6sIe/JOVSzvdcKHAO6lArIupBfk4h+FAsXmqlk3EtOGZwERjMhRYQAszx2OoAon1eix0fe6EJv4hF5Bc6WxNKmfm8ch0hJgaEvY+mGAXN8hFWTFXvTsk+tWXGofL6m9gyUQuMr43qmbVskwIT6ESIGLrqibLLmPcOSTzY0FS7OCipiC2zVzZ/eRUhSjaetalLRRw7g6MC3hdUnVNc4xKAog8KYWjXipSeABI4wmjVsV9G8NO52n2WUeeAuIABvJY20WobiEOCzIOuvlk1Hm+r23dDj4AIw3W9BS2bUm4QKBgQDWYXoehd9fYJPLKdQkZtTmWLRXjFNy2dcJ0FSMJRIPAOQIDKjrmzktzLSquisSyj2/FfOw/UgAMDheY9itIVqt7bcZ0YDZ0D3iUTYx85nJuLv1YLh9pZKf2uva14rjht6hWOTy0nE5k3HjHtKzdP8+HKf6lJk42SZKuShjNkgiowKBgQDIEeTLNWJBLBy1bcmu53YeBiN1BxGNKp8ae/499p4wGgXS1dyYFH3wuGeIh3BepoCsIfLlT5a6M6eXhkOEadcMu/xdhKGypliOkGspA51mkuy7F7c17A486ONril48b4YFNDOHdYcqAp7Qn+jF6ZzExFlqe9tzyjnrNGTeUO6w4wKBgQCKmtNd0Kgu/j4P6KdkMagMleVjhTKe2wERM0S2p3EZijXkjmrYia9aUTOt/lfC+kcZuJOqJtfaZ1LKlDuPFDWQplTvuGhaayzXmjIz8Y/IwEulxjcB5X77I4vCHgGKQbTHFLZR2IWj+BR2B4Oqy0YLXnOsq061VpBPV48pNftFiQKBgQCRXscSjBh3aFj3zu0DhDUD/cvXpaowG279rGiAl2g7ZT0kA7bEXedgeGzp/Bc+/tZxvD0kN186rnuwkqMOXGUgYJsvTEa9azbfZ7olU/YTaOBP1RyPNpTl1wYfxqtQWGxV7acfXts2QC8rQXW+EE+TfWPHBnXfPWo2J5y/GKlGpwKBgBeg5H3WbbU3ul1MHCw1OY/QkQLcqx6Z+SnYsASd6n8UHeITxry5ohZipWMyq4rEv+XmoFtxwOoxKymMTyT3tEONsgUSeZUESwIl6bs6aiDT1AKmpBBrZuN7XAcKjlKCBlrxTv7YMe/BxA+PGasy2FhUeaa8LaNDd9MqU4JQni2m";
    public static final String serverPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp4sjefFg4fSkJwIW9kh2j7HdvQODSdo4FUkLvJDPJOysxvWh+nUrksdHfhWEgSmPaRRk6qdABnBXkXlSfx9qAvix4ORa2KR6Re7BiSfn8VQ/T8snyV0Wvfi+iXvneAFuzzthjiRZUISMadzYnqT1BUGNbUdXuj3hgGzbCJFtmpV2D2lBX0SK6/jxMVCiCM/8QAZ1Er7E8mjLW2zQiGJ6Q31nRRBXrqpWjWSviPhKaax3I8Ip3CJiSa3h/9GgyXmZV+CzqOymIW7dFmGP4YKvOmOJ2Xz8NpYdeQJdJ57lCBkTvPhiVOM9LEkaku5d3ceaLIR9KzSWjxEFV7yH3VDGiQIDAQAB";
    public static void main(String[] args) throws Exception {
        TreeMap<String, Object> params = new TreeMap<String, Object>();
        params.put("userid", "152255855");
        params.put("phone", "189656214201111");

        client(params);

        server();
    }


    public static void client(TreeMap<String, Object> params) throws Exception {
        // 生成RSA签名
        String sign = EncryptUtils.handleRSA(params, clientPrivateKey);
        params.put("sign", sign);
        System.out.println("签名: "+sign);

        String info = JSON.toJSONString(params);
        //随机生成AES密钥
        String aesKey = SecureRandomUtil.getRandom(16);
        System.out.println("AES秘钥: "+aesKey);
        //AES加密数据
        String data = AESUtils.encryptToBase64(ConvertUtils.stringToHexString(info), aesKey, EncryptConstants.ALGORITHM_ECB_PKCS5);

        // 使用RSA算法将商户自己随机生成的AESkey加密
        String encryptKey = RSAUtils.encrypt(aesKey, serverPublicKey);
        System.out.println("加密后的AES秘钥: "+encryptKey);
        System.out.println("加密后的AES秘钥长度: "+encryptKey.length());


        String tmp = encryptKey + data;
        System.out.println(tmp.length());

        Req.data = data;
        Req.encryptKey = encryptKey;
        System.out.println("tmp===>"+tmp);
        System.out.println("加密后的请求数据:\n" + new Req().toString());
    }

    public static void server() throws Exception {

        // 验签
        boolean passSign = EncryptUtils.checkDecryptAndSign(Req.data,
                Req.encryptKey, clientPublicKey, serverPrivateKey);

        if (passSign) {
            // 验签通过
            String aesKey = RSAUtils.decrypt(Req.encryptKey,
                    serverPrivateKey);
            String data = ConvertUtils.hexStringToString(AESUtils.decryptFromBase64(Req.data,
                    aesKey, EncryptConstants.ALGORITHM_ECB_PKCS5));

            JSONObject jsonObj = JSONObject.parseObject(data);
            String userid = jsonObj.getString("userid");
            String phone = jsonObj.getString("phone");

            System.out.println("解密后的明文:userid:" + userid + " phone:" + phone);

        } else {
            System.out.println("验签失败");
        }
    }

    static class Req {
        public static String data;
        public static String encryptKey;

        @Override
        public String toString() {
            return "data:" + data + "\nencryptKey:" + encryptKey;
        }
    }
}
